/**
 * 方法修饰器
 *  因为在类中 方法有分为静态方法和普通方法 所以在使用修饰器的时候 修饰器获取的第一个参数会有区别
 *    当修饰器修饰的是静态方法时
 *      第一个参数是构造函数
 *    当修饰器修饰的是普通方法时
 *      第一个参数时原型对象
 *
 *    第二个参数时 方法名
 *
 *    第三个参数是 方法的属性特征 常见的设置是设置 writabel 设置方法不可重写
 */

{
  // 通过方法装饰器 控制方法不能重写
  const showDecorator: MethodDecorator = (
    target: Object,
    propertyKey: string | symbol,
    descriptor: PropertyDescriptor
  ) => {
    console.log("target", target); // target { show: [Function (anonymous)] }
    console.log("propertyKey", propertyKey); // show
    console.log("descriptor", descriptor); // descriptor {value: [Function (anonymous)],writable: true,enumerable: true,configurable: true}
    /**
     * 第一个参数
     *    如果是静态方法 那么就是构造函数
     *    如果不是静态方法是成员方法 那就是原型对象
     * 第二个参数是方法名称
     * 第三个参数是方法的属性特征
     */

    /**
     * 通过装饰器 默认的第三个参数 设置了这个方法是不可重写的
     */
    descriptor.writable = false;
  };

  class User {
    /**
     * 装饰器放在类上面就是类装饰器 放在方法上面就是方法装饰器
     */
    @showDecorator
    static show() {
      console.log("hello world");
    }
  }

  User.show = () => {
    console.log("尝试重写修饰了 不可重写 的方法");
  };

  /**
   * 这个就是方法装饰器的好用的地方！！  非常强大
   */
  User.show(); // 报错 Cannot assign to read only property 'show' of function'function User() {}
}
